package Market;

import java.util.*;
import edu.iastate.jrelm.rl.SimpleStatelessLearner;
import sim.engine.*;


public class Market extends SimState{
	
	private static final long serialVersionUID = 6628525522939315274L;
												
												/** Priorities counter to fire agents in chosen order */
	  int count = 0;
												/** number of Branches*/
	  private int N;
	  											/** number of Nodes*/
	  private int K;

	  boolean Switch;
	  
	  
	  
	  // GenCo part												
												/** number of GenCos */
	  private int I;
	  											/** GenCos list */
	  private ArrayList GenCoList;
	  											/** Action domains list */
	  private ArrayList ADList; //
	  											/** Learners list */
	  private ArrayList LearnerList;
	  											/** GenCos Data: {Gen ID, at Node, FCost, aT, bT, CapTL, CapTU, Initial Money in pounds} */
	  private double[][] GenCoData;
	  											/** Learning Data: {initial propensity, Cooling, Recency, Experimentation, M1, M2, M3, RIMaxL, RIMaxU, RIMinC, SlopeStart, Reward Selection} */
	  private double[][] LearningData;
	  											/** True Supply Offer: {aT,bT,CapTL,CapTU} */
	  private double[][] TSupplyOffer;
	  											/** Reported Supply Offer: {aR,bR,CapRL,CapRU} */
	  private double[][] RSupplyOffer;
	  											/** Hourly power production quantity by GenCos */
	  private double[][] Commitment;
	  											/** GenCo's accumulative money holding, money (new) = money(previous) + dailyProfit(new) */
	  private double[] GenCoMoney;
	  
	  
	  
	  
	  
	  SimpleStatelessLearner Learner;
	  
// LSE part
												/** number of LSEs */
	  private int J;      
	  private double[][] LSEData;
	  private ArrayList LSEList;
	  private double[][] LoadProfile;
	  private static final int Hours = 24;

// ISO part
	
	  private double [][] LMP;
//-------Constructor----------------------------------------------
    public Market(long seed)
        {
        super(seed);
        }
//-----------------------------------------------------------------
    
    //public void start(long RandomSeed)
    public void start()
        {
        super.start();
        
        Initials.InitGenCo  initG = new Initials.InitGenCo();
        Initials.InitLSE    initL = new Initials.InitLSE();
        Initials.InitBranch initB = new Initials.InitBranch();
        Initials.InitNode initN = new Initials.InitNode();
        
        I = initG.getNGenCo();
        J = initL.getNLSE();
        N = initB.getNBranch();
        K = initN.getNNode();
        
        ElGrid elgrid = new ElGrid();
        GenCoMoney = new double[I];
//----- GenCo--------------------------------------------------------               	
        	
        	//java.util.Random randomSeed = new java.util.Random((int)this.getRngSeed());
        	
for(int d=0;d<5;d++){  
			Switch = false;
			//setSwitch(Switch);
			LearnerList  = new ArrayList();
        	ADList		 = new ArrayList();
        	GenCoList    = new ArrayList();
        	GenCoData    = new double[I][8];
        	LearningData = new double[I][12];
        	TSupplyOffer = new double[I][4];
        	RSupplyOffer = new double[I][4];

       

        	GenCoData    = initG.getGenCoData();  
        	
        	
/* ********* Money update needs to be fixed***************************************
 	
        	        if (d>0){		
               		  for (int i=0;i<I;i++){               			
            		  GenCoData[i][7]= getGenCoMoney()[i];
            		  }	
        	        }
 ***************************************************************************/        	


        	
        	LearningData = initG.getLearningData(); 
        	  
        	for(int i=0; i<I; i++){
        		count++;
        		GenCo gen = new GenCo(GenCoData, LearningData, i, -890999481, this, d, Switch);        	
        		schedule.scheduleOnce(gen, count);        	       	
        	
        		LearnerList.add(gen.getLearner());
        		
        	//elgrid.addGenCoAtNodeK(gen,(i+1));            
      		//GenCoList.add(gen);        		
        	}             	
//----- LSE-------------------------------------------------------- 
        
        	LSEList = new ArrayList();
        	LSEData = new double[J][26];
        	LoadProfile = new double[Hours][J] ;
        	
        	
        	//Initials.InitLSE initL = new Initials.InitLSE();
        	LSEData = initL.getLSEData();
        	
        	for (int h=0; h<Hours; h++){
        		for(int j=0; j<J; j++){ 
        			count++;    		
        			LSE lse = new LSE(LSEData, j, h, this);        	        		
        			schedule.scheduleOnce(lse, count);
       		    
       		    //elgrid.addLSEAtNodeK(lse,(j+1));            
        		//	LSEList.add(lse);                	
        		}
        	}
//----- ISO-------------------------------------------------------- 
        	
        		LMP = new double[24][K];
        		Commitment = new double[24][I];
        		
        		for (int h=0; h<Hours; h++){ 
        			count++;
        			ISO iso = new ISO(I, J, h, this);
        			schedule.scheduleOnce(iso, count);
        		}
           
//----- GenCo--------------------------------------------------------        
    
        		Switch = true;
        		
        		// ArrayList listtemp = getArrayList();
        		 
	 			for(int i=0; i<I; i++){   
	 				count++;
	 				
	 			//	Learner = (SimpleStatelessLearner)LearnerList.get(i);
	 				System.out.println("Ushiol learnel" );
	 				GenCo gen = new GenCo(GenCoData, i, this, d, Switch, LearnerList);        	
	 				schedule.scheduleOnce(gen, count);      
	 			}
      
	 			}
}
//-------Main-----------------------------------------------------
    public static void main(String[] args)
        {
        Market market = new Market(System.currentTimeMillis());
        
        //market.start(System.currentTimeMillis());
        market.start();
        long steps = 0;
        //while(steps < 5000)
        
        for(int i=0; i<1; i++) {

        	market.schedule.step(market);
            steps = market.schedule.getSteps();

           // System.out.println("Steps: " + steps );
            
            }
        
        //OptimalPowerFlow opf = new OptimalPowerFlow();
        System.out.println("Done!!!");
        market.finish();
        System.exit(0);
        }
    
//---------------------------------------------------------------   
   
    public void setLSEList(Object lselist){
    	LSEList.add(lselist);
    	
    }
    
    public void setLoadProfile(double loadprofile, int h, int jj){
 
    	LoadProfile[h][jj] = loadprofile;
    	//System.out.println(jj + "  "+LoadProfile[jj][i]);
    } 
    
    public double[][] getLoadProfile(){
    	return LoadProfile;
    }
    
    public void setTSupplyOffer(double[] tsupplyoffer, int ii){
    	for (int i=0; i<4; i++){
    	TSupplyOffer[ii][i] = tsupplyoffer[i]; 	
    	}
    }
    
    public void setRSupplyOffer(double[] rsupplyoffer, int ii){
    	for (int i=0; i<4; i++){
    	RSupplyOffer[ii][i] = rsupplyoffer[i]; 	
    	}
    }
    
    public double[][] getRSupplyOffer(){
    	return RSupplyOffer;
    }
    
    
    
    public double[][] getTSupplyOffer(){
    	return TSupplyOffer;
    }
   
    public void addAactionDomain(ArrayList adlist){    	
    	ADList.add(adlist);
    }
    
    public void setLearnerList(SimpleStatelessLearner learner){    	
    	LearnerList.add(learner);
    	System.out.println("Seted");
    }
    
    public ArrayList getArrayList(){
    	System.out.println("Returned");
    	return LearnerList;
    	
    }
    
    
    public void addGenCo(Object gencolist ){    	
    	GenCoList.add(gencolist);
    }
    public ArrayList getGenCo(){    	
    	return GenCoList;
    }
    
    public void setLMPList(double[] lmp, int h ){    	 	
    	for (int i=0; i<K; i++){
    		LMP[h][i] = lmp[i];
    	}
    }
   
    public void setSwitch(boolean sw){    	
    	Switch = sw;
    }
    
    public boolean getSwitch(){
    	return Switch;
    }
    
    public void setCommitment(double[] commitment, int h ){   
    	
    	//System.out.println("-----------------------");	 
    	for (int i=0; i<I; i++){
    		Commitment[h][i] = commitment[i];
    	//	System.out.println("hour=  " +h+"  "+Commitment[h][i]);	
    	}
    }
    
    public double[][] getCommitment(){
    	return Commitment;	
    }
    
    public double[][] getLMP(){
    	return LMP;	
    }
    
	public void setGenCoMoney(int i, double gencomoney){
		//GenCoMoney = new double[I];
		GenCoMoney[i] = GenCoMoney[i]+gencomoney;
		
		//if (i==0){
		//System.out.println(GenCoMoney[i]);}
		//System.out.println("i= "+i+" "+GenCoMoney[i]+"   "+gencomoney[i]);
	}

	
	public double[] getGenCoMoney(){		
		return GenCoMoney;
	}
}
